home *** CD-ROM | disk | FTP | other *** search
- Unit DlgHelp;
-
- { Using a message filter to create context sensitive help in a dialog.
-
- Now it's possible to use chained dialogs, each with his own F1 notification
- message. The notification message is send with a wm_Command and a given
- Ctl_ID, so you can use one routine to answer the help button and the F1 key.
- Use an object procedure with ...virtual id_First + Ctl_ID!
-
- Only the last installed filter routine is called. So you must use modal
- dialogs!
-
- Compiler: BP7 with OWL
-
- Written: 7/18/91 By: Pat Ritchey CIS ID: [70007,4660]
- Changed: 5/18/93 By: Michael Denzlein - S.I.P. CIS ID: [100120,2601]
- }
-
- {*************************************************************************}
- {*****************************} Interface {*******************************}
- {*************************************************************************}
-
- uses WinTypes,WinProcs,OWindows,ODialogs,Objects;
-
- {*************************************************************************}
-
- Procedure InstallFilter(AWnd : hWnd; IDNr : Word);
- { Installs filter procedure for window 'AWnd' with the notification message
- wm_Command with 'MsgNr' in wParam. It's possible to chain the filters! }
-
- Procedure RemoveFilter;
- { Removes one filter procedure from the list. }
-
- Procedure DisableHelp;
- Procedure EnableHelp;
- { while WINHELP is called, other help keys should be ignored, so use DisableHelp at
- the beginning of your help routine and EnableHelp at the end. }
-
- {*************************************************************************}
- {***************************} Implementation {****************************}
- {*************************************************************************}
-
- Type PFilterRec = ^TFilterRec;
- TFilterRec = record
- HelpMsgID : Word; { ID to send with the wm_Command notification }
- HelpParent: hWnd; { Parent who receives this message }
- end;
- var
- { Global variables used by MsgFilter functions }
- MsgInstance, { Holds the ProcInstance of MsgFilter }
- OldHook : TFarProc; { The previous hook function }
- HlpFilterColl : PCollection; { Collection to save the message receiver and the ID-Nr }
-
- const
- HlpCollExists : Boolean = False; { Used to handle the HlpFilterColl on the fly }
- DisableHelpFlag : boolean = False; { Used to temporary disable the F1 functionality }
-
- Function MsgFilter(nCode : integer; wParam : word; var Msg : TMsg) : longint; export;
- begin
- MsgFilter := 0;
- if nCode<0 then begin
- MsgFilter := DefHookProc(nCode,wParam,Longint(@Msg),@OldHook);
- exit;
- end;
- { if a help dialog box is already displayed don't display another }
- if DisableHelpFlag then
- exit;
- { if this is not a dialog box message then ignore it }
- if nCode<>MSGF_DialogBox then
- exit;
- { Ignore all but KEYDOWN messages }
- if Msg.message<>WM_KEYDOWN then
- exit;
- { Ignore all keys except F1 }
- if Msg.wParam<>VK_F1 then
- exit;
- { at this point we know that the message is an F1 keypress in a
- dialog box. Set the return value to signify that *WE* have handled
- the message and then send a message to the window that will process
- the help message, passing the window handle of the control with focus
- in lParamLo }
- MsgFilter := 1;
- with TFILTERREC(HlpFilterColl^.At(HlpFilterColl^.Count-1)^) do
- SendMessage(HelpParent, wm_Command, HelpMsgID, Msg.hWnd);
- end;
-
- Procedure InstallFilter(AWnd : hWnd; IDNr : Word);
- var Puf : PFilterRec;
- begin
- if not HlpCollExists then begin { if there is no collection yet }
- HlpFilterColl := new(PCollection, init(1,1)); { create one }
- HlpCollExists := True;
- MsgInstance := MakeProcInstance(@MsgFilter,hInstance); { and the filter procedure }
- OldHook := SetWindowsHook(WH_MSGFilter,MsgInstance);
- DisableHelpFlag := false;
- end;
- Puf := New(PFilterRec); { add the data to the collection }
- Puf^.HelpParent := AWnd;
- Puf^.HelpMsgID := IDNr;
- HlpFilterColl^.Insert(Puf);
- end;
-
- Procedure RemoveFilter;
- begin
- if HlpCollExists then begin { if there is a collection continue }
- HlpFilterColl^.AtDelete(HlpFilterColl^.Count-1); { delete the last entry }
- if HlpFilterColl^.Count=0 then begin { if it was the very last }
- UnhookWindowsHook(WH_MSGFILTER, MsgInstance); { kill filter procedure }
- FreeProcInstance(MsgInstance);
- dispose(HlpFilterColl, Done); { and kill the collection }
- HlpCollExists := False;
- end;
- end;
- end;
-
- Procedure DisableHelp;
- begin
- DisableHelpFlag := True;
- end;
-
- Procedure EnableHelp;
- begin
- DisableHelpFlag := False;
- end;
-
- {*************************************************************************}
- {*************************************************************************}
- {*************************************************************************}
-
- begin
- HlpFilterColl := nil;
- end.
-